package com.crm.aop;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.crm.annotation.SystemServiceLog;
import com.crm.model.BaseModel;
import com.crm.model.SysLog;
import com.crm.model.SysUser;
import com.crm.model.entity.LogEntity;
import com.crm.service.SysLogService;
import com.crm.util.JsonUtil;
import com.crm.util.SessionModel;
import com.crm.util.SessionUtils;
import com.crm.util.UUIDUtil;
import com.crm.util.ZhCrmLogInException;

@Aspect
@Component
public class SystemLogAspect {

	private static final Logger logger = Logger.getLogger(SystemLogAspect.class);

	@Autowired
	private SysLogService sysLogService;
	private static String desc = "";
	private static String type = "";

	@Pointcut("@annotation(com.crm.annotation.SystemServiceLog)")
	public void controllerAspect() {
	}

	/**
	 * 
	 * @Description : 获取ip号
	 * @author zealot
	 * @param @param request
	 * @param @return
	 * @return String
	 * @version 创建时间 : 2016年11月17日 下午6:37:30
	 * @thorws
	 */
	public String getRemoteHost(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
			ip = request.getRemoteAddr();
		}
		return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
	}

	/**
	 * 
	 * @Description : 日志切入点
	 * @author zealot
	 * @param @param joinPoint
	 * @return void
	 * @version 创建时间 : 2016年11月17日 下午6:37:46
	 * @throws Exception 
	 * @thorws
	 */
	@Before("controllerAspect()")
	public void doBefore(JoinPoint joinPoint) throws Exception {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getResponse();

		SysUser user = (SysUser) SessionUtils.get(SessionModel.SESSION_USER);

		String ip = getRemoteHost(request);
		try {
			SysLog log = new SysLog();
			log.setLogId(UUIDUtil.getUUID());
			log.setContent(getControllerMethodDescription(joinPoint));
			log.setIp(ip);
			log.setLogHtml(desc);
			log.setType(type); 
			log.setAccount(user.getAccount());
//			log.setAccount("admin");
//			log.setUserName("admin"); 
			log.setUserName(user.getRealName()); 
			sysLogService.insert(log);
		} catch (Exception e) {
			throw new ZhCrmLogInException("用户会话不存在");
		}
	}

	/**
	 * 
	 * @Description : 获取注解内容
	 * @author zealot
	 * @param @param
	 *            joinPoint
	 * @param @return
	 * @param @throws
	 *            Exception
	 * @return String
	 * @version 创建时间 : 2016年11月17日 下午6:25:20
	 * @thorws
	 */
	public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		BaseModel parent = new BaseModel();
		Class targetClass = Class.forName(targetName);
		Method[] methods = targetClass.getMethods();
		LogEntity map = new LogEntity();
		Method[] arrayOfMethod1;
		int j = (arrayOfMethod1 = methods).length;
		for (int i = 0; i < j; i++) {
			Method method = arrayOfMethod1[i];
			if (method.getName().equals(methodName)) {
				Class[] clazzs = method.getParameterTypes();
				if (clazzs.length == arguments.length) {
					desc = ((SystemServiceLog) method.getAnnotation(SystemServiceLog.class)).description();
					type = ((SystemServiceLog) method.getAnnotation(SystemServiceLog.class)).type();
					map.setDescription(((SystemServiceLog) method.getAnnotation(SystemServiceLog.class)).description());
					Map m = new HashMap();
					for (int num = 0; num < clazzs.length; num++) {
						if(BaseModel.class.isAssignableFrom(clazzs[num])){
							m.put(clazzs[num].toString(), arguments[num] == null ? "empty" : JsonUtil.toJsonStr(arguments[num]));
						}else{
							m.put(clazzs[num].toString(), arguments[num] == null ? "empty" : arguments[num].toString());
						}
					}
					map.setArg(m);
					break;
				}
			}
		}
		return JsonUtil.toJsonStr(map);
	}
}
